package postgres

import (
	"context"
	"quipus/internal/database/model"
	apb "quipus/proto/gen/assist"

	_ "github.com/jackc/pgx/v5/stdlib"
	_ "github.com/joho/godotenv/autoload"
	"github.com/pkg/errors"
)

func (p *PGDB) GetLLMAssistant(ctx context.Context, assistantId int32) (*model.LlmAssistant, error) {
	p.query()
	qdo := q.WithContext(ctx)
	assistant := qdo.LlmAssistant

	return assistant.Where(q.LlmAssistant.ID.Eq(assistantId)).First()
}

func (p *PGDB) CreateLLMAssistant(ctx context.Context, create *model.LlmAssistant) error {
	p.query()
	qdo := q.WithContext(ctx)
	err := qdo.LlmAssistant.Create(create)
	if err != nil {
		return errors.Wrap(err, "failed to create llm assistant")
	}
	return nil
}

func (p *PGDB) DeleteLLMAssistant(ctx context.Context, assistantId int32) error {
	p.query()
	assistant := q.WithContext(ctx).LlmAssistant
	_, err := assistant.Where(q.LlmAssistant.ID.Eq(assistantId)).Delete()
	if err != nil {
		return errors.Wrap(err, "failed to delete assistant")
	}
	return nil
}

func (p *PGDB) UpdateLLMAssistant(ctx context.Context, update *apb.UpdateLLMAssistant) (*model.LlmAssistant, error) {
	p.query()
	qdo := q.WithContext(ctx)
	if update.Id < 0 {
		return nil, errors.New("id is required")
	}

	assistant := qdo.LlmAssistant
	assistant = assistant.Where(q.LlmAssistant.ID.Eq(update.Id))

	updateValue := &model.LlmAssistant{}
	updateValue.ID = update.Id
	if update.UpdatedTs > 0 {
		updateValue.UpdatedTs = update.UpdatedTs
	}

	if update.Name != "" {
		updateValue.Name = update.Name
	}

	if update.ModelId > 0 {
		updateValue.ModelID = update.ModelId
	}

	if update.Prompt != "" {
		updateValue.SystemPrompt = update.Prompt
	}

	if len(update.Description) > 0 {
		updateValue.Description = update.Description
	}

	_, e := assistant.Updates(updateValue)

	return updateValue, e
}

func (p *PGDB) ListLLMAssistants(ctx context.Context, find *apb.FindLLMAssistant) ([]*model.LlmAssistant, int32, error) {
	p.query()
	qdo := q.WithContext(ctx)
	assistant := qdo.LlmAssistant
	if find.Id > 0 {
		assistant = assistant.Where(q.LlmAssistant.ID.Eq(find.Id))
	}
	if find.ModelId > 0 {
		assistant = assistant.Where(q.LlmAssistant.ModelID.Eq(find.ModelId))
	}
	if len(find.Name) > 0 {
		assistant = assistant.Where(q.LlmAssistant.Name.Eq(find.Name))
	}

	if find.TenantId > 0 {
		assistant = assistant.Where(q.LlmAssistant.TenantID.Eq(find.TenantId))
	}

	limit := find.Limit
	if limit == 0 {
		limit = 10
	}

	ps, c, e := assistant.FindByPage(int(find.Offset), int(limit))

	return ps, int32(c), e
}
